package com.aps.common.entity;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author nbZhuozh
 * @Date 2025-11-21  15:46
 *
 * 使用当前工具类的参数 必须继承 ExtMap 类
 **/
@Slf4j
public class ExtMapUtils {

    protected static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    //按具体类的属性名称 +  类型 转换json 数据
    public static Map<String, Object> extractExtMap(Class<?> clazz , String json) {
        if(StringUtils.isEmpty(json)) {
            return Collections.emptyMap();
        }
        Map<String, Class<?>> resultMap = new HashMap<String, Class<?>>();
        //获取当前自身类的属性（需要 json 匹配对应的 属性名称和类型）
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            Class<?> type = declaredField.getType();
            String name = declaredField.getName();
            resultMap.put(name, type);
        }
        return convertToExtMap(resultMap, json);
    }



    //按照属性名称和类型 转成对应map
    public static Map<String, Object> convertToExtMap(Map<String, Class<?>> filedsMap , String jsonStr) {
        if(jsonStr == null || jsonStr.isEmpty()) {
            return Collections.emptyMap();
        }
        Map<String, Object> convertMap = new HashMap<>();
        try {
            Map<String, Object> rawMap = OBJECT_MAPPER.readValue(jsonStr, new TypeReference<Map<String, Object>>() {});
            if(filedsMap == null || filedsMap.isEmpty()) {
                return rawMap;
            }
            //转换类型
            for (Map.Entry<String, Class<?>> entry : filedsMap.entrySet()) {
                String filedName = entry.getKey(); //需要转换的属性名
                Class<?> clazzObj = entry.getValue(); //对应属性的 转换类型
                if(rawMap.containsKey(filedName)) {
                    Object originalValue = rawMap.get(filedName);
                    //判断是否需要继续转换 : 需要满足 当前值不为空
                    if(originalValue != null && !clazzObj.isInstance(originalValue)) {
                        try{
                            //do convert  实际转换在这里！！！！！
                            Object convertedValue = OBJECT_MAPPER.convertValue(originalValue, clazzObj);
                            convertMap.put(filedName, convertedValue);
                        } catch (IllegalArgumentException e) {
                            log.error("Failed to convert value for key '{}' from type '{}' to '{}'. Keeping original value.",
                                    filedName, originalValue.getClass().getName(), clazzObj.getName(), e);
                        }
                    }
                }
            }
        } catch (JsonProcessingException e) {
            log.error("extToMap error : {}", e.getMessage());
        }
        return convertMap;
    }


    @SneakyThrows
    public static String toJsonStr(Object obj) {
        if(obj == null) {
            return null;
        }
        return OBJECT_MAPPER.writeValueAsString(obj);
    }


}
